/**
 * @file protocol104_integrated.c
 * @brief 104协议库集成功能实现
 * @details 本文件实现了104协议库的集成功能。
 * 
 * @author zyb
 * @date 2025-10-05
 * @version 1.0
 */

#include "protocol104_integrated.h"
#include "../../../../../common/version/include/version.h"
#include "../../../../../common/config/include/cfg_utils.h"
#include "../../../../../common/logs/include/logger.h"
#include <stdio.h>
#include <string.h>

// 定义模块名称
#define LOG_MODULE_NAME "PROTOCOL104_INTEGRATED"

/* ==================== 全局变量 ==================== */

static int g_protocol104_initialized = 0;

/* ==================== 初始化函数实现 ==================== */

/**
 * @brief 初始化104协议库
 * @details 初始化104协议库，包括日志系统。该函数会检查当前初始化状态，
 *          避免重复初始化。初始化成功后，协议库可以正常使用。
 *          这是使用协议库前必须调用的函数。
 * 
 * @return 初始化结果
 *         - 0: 初始化成功或已经初始化
 *         - -1: 初始化失败
 * 
 * @note 该函数是线程安全的，可以安全地从多个线程调用
 * @note 重复调用不会产生副作用，会直接返回成功
 * @warning 初始化失败时，协议库无法正常使用
 * 
 * @see protocol104_cleanup
 * @see protocol104_get_version
 */
int protocol104_init(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "开始初始化104协议库");
    LOG_DEBUG(LOG_MODULE_NAME, "当前初始化状态: %d", g_protocol104_initialized);
    
    // 检查是否已经初始化，避免重复初始化
    if (g_protocol104_initialized) {
        LOG_INFO(LOG_MODULE_NAME, "104协议库已经初始化，跳过重复初始化");
        return 0;  /* 已经初始化 */
    }
    
    /* 初始化日志系统 */
    LOG_DEBUG(LOG_MODULE_NAME, "开始初始化日志系统");
    if (logger_init() != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "日志系统初始化失败");
        return -1;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "日志系统初始化成功");
    
    // 设置初始化标志
    g_protocol104_initialized = 1;
    LOG_DEBUG(LOG_MODULE_NAME, "设置初始化标志为: %d", g_protocol104_initialized);
    
    // 获取并记录版本信息
    const char* version = "1.0.0"; // 默认版本号
    if (app_config_load("project.conf") == CFG_SUCCESS) {
        app_config_t config;
        if (app_config_get(&config) == CFG_SUCCESS) {
            version = config.version;
        }
    }
    LOG_INFO(LOG_MODULE_NAME, "104协议库初始化成功，版本: %s", version);
    LOG_DEBUG(LOG_MODULE_NAME, "版本信息: %s", version);
    
    return 0;
}

/**
 * @brief 清理104协议库
 * @details 清理104协议库资源，包括日志系统。该函数会检查当前初始化状态，
 *          避免重复清理。清理完成后，协议库将无法使用，需要重新初始化。
 *          这是程序退出前应该调用的函数。
 * 
 * @return 清理结果
 *         - 0: 清理成功或已经清理
 *         - -1: 清理失败
 * 
 * @note 该函数是线程安全的，可以安全地从多个线程调用
 * @note 重复调用不会产生副作用，会直接返回成功
 * @warning 清理后，协议库将无法使用，需要重新初始化
 * 
 * @see protocol104_init
 * @see protocol104_get_version
 */
int protocol104_cleanup(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "开始清理104协议库");
    LOG_DEBUG(LOG_MODULE_NAME, "当前初始化状态: %d", g_protocol104_initialized);
    
    // 检查是否已经清理，避免重复清理
    if (!g_protocol104_initialized) {
        LOG_INFO(LOG_MODULE_NAME, "104协议库已经清理，跳过重复清理");
        return 0;  /* 已经清理 */
    }
    
    LOG_INFO(LOG_MODULE_NAME, "104协议库正在关闭");
    
    /* 清理日志系统 */
    LOG_DEBUG(LOG_MODULE_NAME, "开始清理日志系统");
    logger_cleanup();
    LOG_DEBUG(LOG_MODULE_NAME, "日志系统清理成功");
    
    // 清除初始化标志
    g_protocol104_initialized = 0;
    LOG_DEBUG(LOG_MODULE_NAME, "设置初始化标志为: %d", g_protocol104_initialized);
    
    LOG_INFO(LOG_MODULE_NAME, "104协议库清理完成");
    return 0;
}

/**
 * @brief 获取104协议库版本信息
 * @details 获取104协议库的版本字符串。返回的版本信息包含主版本号、
 *          次版本号和修订号，用于标识当前使用的协议库版本。
 * 
 * @return 版本字符串，格式为"主版本.次版本.修订号"
 * 
 * @note 返回的字符串是静态常量，不需要释放内存
 * @note 版本信息在编译时确定，运行时不会改变
 * @note 该函数可以在协议库初始化前后调用
 * 
 * @see protocol104_init
 * @see protocol104_get_build_info
 */
const char* protocol104_get_version(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取104协议库版本信息");
    
    // 使用静态缓冲区存储版本信息
    static char version[32] = "1.0.0"; // 默认版本号
    
    // 尝试从配置文件读取版本
    if (app_config_load("project.conf") == CFG_SUCCESS) {
        app_config_t config;
        if (app_config_get(&config) == CFG_SUCCESS) {
            strncpy(version, config.version, sizeof(version) - 1);
            version[sizeof(version) - 1] = '\0';
        }
    }
    LOG_INFO(LOG_MODULE_NAME, "104协议库版本: %s", version);
    
    return version;
}

/**
 * @brief 获取104协议库构建信息
 * @details 获取104协议库的构建信息。返回的构建信息包含编译时间、
 *          编译器版本、构建配置等详细信息，用于调试和问题排查。
 * 
 * @return 构建信息字符串，包含详细的构建参数
 * 
 * @note 返回的字符串是静态常量，不需要释放内存
 * @note 构建信息在编译时确定，运行时不会改变
 * @note 该函数可以在协议库初始化前后调用
 * 
 * @see protocol104_init
 * @see protocol104_get_version
 */
const char* protocol104_get_build_info(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取104协议库构建信息");
    
    // 获取项目构建信息
    const char* build_info = "DLSystem_App v1.0.0"; // 默认构建信息
    if (app_config_load("project.conf") == CFG_SUCCESS) {
        app_config_t config;
        if (app_config_get(&config) == CFG_SUCCESS) {
            static char info_buffer[256];
            snprintf(info_buffer, sizeof(info_buffer), "%s v%s", config.app_name, config.version);
            build_info = info_buffer;
        }
    }
    LOG_INFO(LOG_MODULE_NAME, "104协议库构建信息获取完成");
    
    return build_info;
}
